/**
 *	@file	bc_use_sub.c
 *	@brief	ボングリジュース使用デモ サブ
 *	@author	Miyuki Iwasawa
 *	@date	08.11.06
 *
 */

#include "common.h"
#include "system/procsys.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/snd_tool.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/pmfprint.h"
#include "system/buflen.h"
#include "system/window.h"
#include "system/brightness.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/palanm.h"
#include "system/wipe.h"
#include "system/window.h"
#include "system/font_arc.h"
#include "system/winframe.naix"
#include "gflib/touchpanel.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_bong_use.h"

#include "savedata/config.h"
#include "application/bong_case.h"
#include "bc_sys.h"
#include "bc_use.h"
#include "bc_use_sub.h"
#include "bc_snd_def.h"

#include "bong_use_gra.naix"
#include "data/clact_util/clact_header.naix"

#include "bc_tbl.dat"

#ifdef DEBUG_ONLY_FOR_iwasawa
// #undef IWASAWA_PRINT
// #define IWASAWA_PRINT(...) ((void) 0)
#endif

enum{
 EXE_CODE_USE,
 EXE_CODE_BACK,
 EXE_CODE_UP,
 EXE_CODE_DOWN,
 EXE_CODE_MAX,
};

//スターアニメエフェクト制御構造体
typedef struct _STAR_EFF{
	BC_USEWORK*	app_wk;

	u8	mode;
	u8	seq;
	u8	time;

	fx32	ds;
	u16		rot;
	s16		rot_dif;
	VecFx32	scale;

	CLACT_WORK_PTR act;
}STAR_EFF;

//ポケモンスプライト拡縮アニメ
typedef struct _POKE_AFFINE_EFF{
	BC_USEWORK* app_wk;

	u8	time;
	u8	seq;
	u8	spd;
}POKE_AFFINE_EFF;

//ポケモンパーティクルアニメ
typedef struct _POKE_PARTICLE_EFF{
	BC_USEWORK* app_wk;

	u8	time;
	u8	seq;
	u8	ct;
}POKE_PARTICLE_EFF;

#define PERFORMANCE_VALUE(x,idx)	(((x) >> (PERFORMANCE_BIT_SHIFT*(idx))) & 0x07)

////////////////////////////////////////////////////////////////
///データ定義
static const TCATS_OAM_INIT bonguse_coi = {
	0,128,		///< メイン	OAM管理領域・開始/終了
	0,32,		///< メイン	アフィン管理領域・開始/終了
	0,128,		///< サブ	OAM管理領域・開始/終了
	0,32,		///< サブ	アフィン管理領域・開始/終了
};
static const TCATS_CHAR_MANAGER_MAKE bonguse_ccmm = {
	BONGUSE_ACTRES_MAX,	//ID制御数
	16*1024,	//メイン画面管理サイズ(byte単位) 0/64kbyte
	16*1024,	//サブ画面管理サイズ(byte単位) 0/16kbyte
	GX_OBJVRAMMODE_CHAR_1D_32K,	//メインOBJモード指定
	GX_OBJVRAMMODE_CHAR_1D_32K,	//サブOBJモード指定
};

///TCATS_RES_ARC
static const TCATS_RESOURCE_FILE_LIST bonguse_actres_list = {
	NARC_clact_header_bong_use_chr_resdat,	// キャラクタ
	NARC_clact_header_bong_use_pal_resdat,		// パレット
	NARC_clact_header_bong_use_cell_resdat,	// セル
	NARC_clact_header_bong_use_canm_resdat,	// セルアニメ
	TCATS_RESID_NULL,							// マルチセル
	TCATS_RESID_NULL,							// マルチセルアニメ
	NARC_clact_header_bong_use_celact_cldat		// ヘッダー
};

////////////////////////////////////////////////////////////////
///プロトタイプ
////////////////////////////////////////////////////////////////
static void BongUseVBlank(void * work);

static int sub_InputExe(BC_USEWORK* wk,int code);
static int sub_KeyInput(BC_USEWORK* wk);
static int sub_TouchInput(BC_USEWORK* wk,BOOL* touch_f);


static void sub_VBankSet(void);
static void sub_BGLInit(BC_USEWORK* wk);
static void sub_BGLRelease(BC_USEWORK* wk);
static void sub_2DResInit(BC_USEWORK* wk);
static void sub_2DResRelease(BC_USEWORK* wk);
static void sub_MsgDataInit(BC_USEWORK* wk);
static void sub_MsgDataRelease(BC_USEWORK* wk);
static void sub_BmpWinAdd(BC_USEWORK* wk);
static void sub_BmpWinDel(BC_USEWORK* wk);

static void sub_ActorSysInit(BC_USEWORK* wk);
static void sub_ActorSysRelease(BC_USEWORK* wk);
static void sub_ActorInit(BC_USEWORK* wk);
static void sub_ActorRelease(BC_USEWORK* wk);
static void sub_ActorObjMake(BC_USEWORK* wk);
static void sub_ActorObjDelete(BC_USEWORK* wk);

static void sub_GetPokeParam(BC_USE_POKE* poke,const POKEPARTY* party,POKEMON_PARAM* pp,u8 idx,int heapID);
static void sub_DelPokeParam(BC_USE_POKE* poke);
static void sub_UseJuice(BC_USEWORK* wk);

static void sub_MsgWinDraw(BC_USEWORK* wk);
static void sub_MsgPut(BC_USEWORK* wk,MSG_IDX idx);

static void sub_PageDraw(BC_USEWORK* wk,int pos);
static void sub_PerformanceParamDraw(BC_USEWORK* wk,BC_USE_POKE* poke,u8 prm_idx);
static void sub_PerformanceDraw(BC_USEWORK* wk,BC_USE_POKE* poke);
static void sub_StarViewSet(BC_USEWORK* wk,int idx,u8 anm_no,BOOL draw_f);

static void sub_StarEffSet(BC_USEWORK* wk,u8 prm_id,u8 mode);
static void tcb_StarEff( TCB_PTR tcb, void* p_work );

static void sub_PokeAffineEffSet(BC_USEWORK* wk);
static void tcb_PokeAffineEff( TCB_PTR tcb, void* p_work );
static void sub_PokeParticleEffSet(BC_USEWORK* wk);
static void tcb_PokeParticleEff( TCB_PTR tcb, void* p_work );

////////////////////////////////////////////////////////////////
///グローバル関数
////////////////////////////////////////////////////////////////
/**
 *	@brief	リソース初期化
 */
void BongUseResInit(BC_USEWORK* wk)
{
	sub_BGLInit( wk );
	sub_2DResInit( wk );
	sub_MsgDataInit( wk );
	sub_BmpWinAdd( wk );
	sub_ActorInit( wk );

	wk->p3d_wk = BongUse3D_Init(wk->heapID);

	sys_VBlankFuncChange(BongUseVBlank, wk);
}

/**
 *	@brief	リソース解放
 */
void BongUseResRelease(BC_USEWORK* wk)
{
	BongUse3D_Release(wk->p3d_wk);
	sub_ActorRelease( wk );
	sub_BmpWinDel( wk );
	sub_MsgDataRelease( wk );
	sub_2DResRelease( wk );
	sub_BGLRelease( wk );
}

/**
 *	@brief	初期画面描画
 */
void BongUseInitialDraw(BC_USEWORK* wk)
{
	int i;

	BCUseSub_ButtonWrite(wk,BTN_ACTIVE);

	//タイトル描画
	MSGMAN_GetString(wk->msg.man,msg_title,wk->msg.str);
	GF_STR_PrintColor( &wk->win[WIN_TITLE], FONT_SYSTEM, wk->msg.str,
		0,0, MSG_NO_PUT, FCOL_N_BLACK, NULL );
	GF_BGL_BmpWinOnVReq(&wk->win[WIN_TITLE]);

	//パラメータ名描画
	for(i = 0;i < PM_PERFORMANCE_MAX;i++){
		int idx = g_PerformancePosTbl[i];
		MSGMAN_GetString(wk->msg.man,msg_param01+idx,wk->msg.str);
		GF_STR_PrintColor( &wk->win[WIN_PRM01+i], FONT_SYSTEM, wk->msg.str,
			4,0, MSG_NO_PUT, FCOL_N_BLACK, NULL );
		GF_BGL_BmpWinOnVReq(&wk->win[WIN_PRM01+i]);
	}
	sub_PageDraw(wk,wk->pos);
}


/**
 *	@brief	ポケモンデータ収集
 */
void BCUseSub_GetPokeParam(BC_USEWORK* wk)
{
	int i,max,num;
	POKEMON_PARAM* pp;

	wk->party_sv = SaveData_GetTemotiPokemon(wk->save);

	max = PokeParty_GetPokeCount(wk->party_sv);

	num = 0;
	for(i = 0;i < max;i++){
		pp = PokeParty_GetMemberPointer(wk->party_sv,i);

		if(PokeParaGet(pp,ID_PARA_tamago_flag,NULL)){
			continue;
		}
		sub_GetPokeParam(&wk->poke[num++],wk->party_sv,pp,i,wk->heapID);
	}
	wk->poke_num = num;

}

/**
 *	@brief	ポケモンパラメータ破棄
 */
void BCUseSub_DelPokeParam(BC_USEWORK* wk)
{
	int i;

	for(i = 0;i < wk->poke_num;i++){
		sub_DelPokeParam(&wk->poke[i]);
	}
}

/**
 *	@brief	ボタン描画
 */
void BCUseSub_ButtonWrite(BC_USEWORK* wk,BTN_STATE state)
{
	int i;
	static const GF_PRINTCOLOR col[] = {
	 GF_PRINTCOLOR_MAKE(FBMP_COL_RED,FBMP_COL_WHITE,0),
	 GF_PRINTCOLOR_MAKE(FBMP_COL_BLUE,FBMP_COL_WHITE,0),
	};

	switch(state){
	case BTN_PASSIVE:
		GF_BGL_BmpWinOffVReq(&wk->win[WIN_USE]);
		CLACT_SetDrawFlag(wk->pAct[ACT_USE], FALSE );
		CLACT_SetDrawFlag(wk->pAct[ACT_BACK], FALSE );
		break;
	case BTN_ACTIVE:
		GF_BGL_BmpWinDataFill( &wk->win[WIN_USE], 0);

		for(i = 0;i < 2;i++){
			MSGMAN_GetString(wk->msg.man,msg_use+i,wk->msg.str);
			GF_STR_PrintColor( &wk->win[WIN_USE], FONT_TOUCH, wk->msg.str,
				0,4+(i*24), MSG_NO_PUT, col[i], NULL );
			CLACT_SetDrawFlag(wk->pAct[ACT_USE+i], TRUE );
		}
		GF_BGL_BmpWinOnVReq(&wk->win[WIN_USE]);
		break;
	case BTN_ANM_USE:
	case BTN_ANM_BACK:
		CLACT_AnmChg(wk->pAct[ACT_USE+state], ANM_USE_A+(state*2));
		CLACT_AnmReStart( wk->pAct[ACT_USE+state]);
		break;
	}
}

/**
 *	@brief	入力取得
 */
int BCUseSub_InputCheck(BC_USEWORK* wk)
{
	int ret;
	BOOL touch_f = FALSE;

	ret = sub_TouchInput(wk,&touch_f);
	if(touch_f){
		return ret;
	}
	return sub_KeyInput(wk);
}

/**
 *	@brief	使うエフェクト再生シーケンス
 */
int BCUseSubSeq_UseEffect(BC_USEWORK* wk)
{
	switch(wk->sub_seq){
	case 0:	//ポットアニメ再生
		if(CLACT_AnmActiveCheck( wk->pAct[ACT_USE] )){
			return FALSE;
		}
		BCUseSub_ButtonWrite(wk,BTN_PASSIVE);
		sub_MsgWinDraw(wk);
		sub_MsgPut(wk,MIDX_USE);

		CLACT_SetDrawFlag(wk->pAct[ACT_POT], TRUE );
		CLACT_AnmChg(wk->pAct[ACT_POT], ANM_POT_UP);
		CLACT_AnmReStart( wk->pAct[ACT_POT]);
		Snd_SePlay(SE_BCUSE_POT_APPEAR);
		wk->sub_seq++;
		break;
	case 1:
		if(CLACT_AnmActiveCheck( wk->pAct[ACT_POT] )){
			return FALSE;
		}
		CLACT_AnmChg(wk->pAct[ACT_POT], ANM_POT_ROT);
		CLACT_AnmReStart( wk->pAct[ACT_POT]);
		wk->sub_seq++;
		break;
	case 2:
		if(CLACT_AnmActiveCheck( wk->pAct[ACT_POT] )){
			return FALSE;
		}
		sub_PokeAffineEffSet(wk);
		wk->sub_seq++;
		break;
	case 3:
		if(wk->eff_tcb_ct){
			return FALSE;
		}
		CLACT_SetDrawFlag(wk->pAct[ACT_POT], FALSE );
		sub_PokeParticleEffSet(wk);
		wk->sub_seq++;
		break;
	case 4:
		if(wk->eff_tcb_ct){
			return FALSE;
		}
//		WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT, WIPE_TYPE_FADEOUT,
//			WIPE_FADE_WHITE, WIPE_DEF_DIV, WIPE_DEF_SYNC*2, wk->heapID);
		wk->sub_seq = 6;
		break;
	case 5:
		if( !WIPE_SYS_EndCheck()){
			break;
		}
		WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEIN, WIPE_TYPE_FADEIN,
			WIPE_FADE_WHITE, WIPE_DEF_DIV, WIPE_DEF_SYNC*2, wk->heapID);
		wk->sub_seq++;
		break;
	default:
		if( !WIPE_SYS_EndCheck()){
			break;
		}
		wk->sub_seq = 0;
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	なにも変わらなかったメッセージ表示
 */
int BCUseSubSeq_NoChangeMsg(BC_USEWORK* wk)
{
	switch(wk->sub_seq){
	case 0:
		sub_MsgWinDraw(wk);
		sub_MsgPut(wk,MIDX_NO_CHANGE);
		wk->sub_seq++;
		break;
	case 1:
		if( GF_MSG_PrintEndCheck( wk->msg_idx )){
			break;
		}
		wk->sub_seq = 0;
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	結果再生シーケンス
 */
int BCUseSubSeq_ResultCheck(BC_USEWORK* wk)
{
	int prm_idx = g_PerformancePosTbl[wk->res_ct];

	switch(wk->sub_seq){
	case 0:
		wk->wait = 0;
		wk->diff_ct = 0;
		if(wk->diff_prm[wk->res_ct] < 0){
			wk->diff_num = -wk->diff_prm[wk->res_ct];
			Snd_SePlay(SE_BCUSE_PARAM_DOWN);
		}else{
			wk->diff_num = wk->diff_prm[wk->res_ct];
			Snd_SePlay(SE_BCUSE_PARAM_UP);
		}
		wk->sub_seq++;
		//スルー↓
	case 1:
		//星アニメーション追加
		if(wk->wait-- > 0){
			break;
		}
		if(wk->diff_prm[wk->res_ct] < 0){
			sub_StarEffSet(wk,prm_idx,1);
		}else{
			sub_StarEffSet(wk,prm_idx,0);
		}

		if(wk->diff_ct >= wk->diff_num){
			wk->sub_seq++;
			break;
		}
		wk->wait = 15;
		break;
	case 2:
		if(wk->eff_tcb_ct){
			break;
		}
		sub_PerformanceParamDraw(wk,&wk->poke[wk->pos],prm_idx);

		sub_MsgWinDraw(wk);
		if(wk->diff_prm[wk->res_ct] < 0){
			sub_MsgPut(wk,MIDX_PRM_DOWN01 + prm_idx);
		}else{
			sub_MsgPut(wk,MIDX_PRM_UP01 + prm_idx);
		}
		wk->sub_seq++;
		break;
	default:
		if( GF_MSG_PrintEndCheck( wk->msg_idx )){
			break;
		}
		wk->sub_seq = 0;
		return TRUE;
	}
	return FALSE;
}

////////////////////////////////////////////////////////////////
///デバッグ関数
////////////////////////////////////////////////////////////////
#ifdef PM_DEBUG

// 表示モード（表示文字列に作用するだけ。データには干渉しないので注意）
enum
{
	DEBUG_DISP_MODE_BEFORE = 0,
	DEBUG_DISP_MODE_AFTER,
};

//--------------------------------------------------------------
///	デバッグ用 パフォーマンス保持ワーク
//==============================================================
typedef struct {
	s8 cond;
	s8 rev;
	s8 add;
	s8 base;

	s8 min;
	s8 max;
	s8 result;
	s8 padding[1];
} DEBUG_PERFORMANCE_DISP;

// poke_tool.c で定義されている
extern BOOL DebugPokeTool_CallByBCUseFlag;

// シングルトン
static DEBUG_PERFORMANCE_DISP wkDebugPer[ PM_PERFORMANCE_MAX ] = {0};

// 公開関数
void BCUse_DebugSetPerformance( int perIdx, int cond, int rev, int add, int base, int min, int max, int result );

#define DEBUG_SUB_PAL (15)

#define DEBUG_STR_H (4)
#define DEBUG_STR_W (24)

#define DEBUG_CAP_H (2)
#define DEBUG_CAP_W (16)
#define DEBUG_CAP_CGX (1+20)
#define DEBUG_CGX_BASE ( DEBUG_CAP_CGX + DEBUG_CAP_W * DEBUG_CAP_H)

#define DEBUG_POS(idx) ( DEBUG_CAP_H + DEBUG_STR_H * idx )
#define DEBUG_CGX(idx) ( DEBUG_CGX_BASE + idx * DEBUG_STR_H * DEBUG_STR_W ) // BGに使用しているキャラが20ぐらい

#define DEBUG_PRINT_NUM ( PM_PERFORMANCE_MAX + 1 )

static const BMPWIN_DAT c_DebugBmpWinData[ DEBUG_PRINT_NUM ] = {
	{ UFRM_BACK, 0, 0,			  DEBUG_CAP_W, DEBUG_CAP_H, DEBUG_SUB_PAL, DEBUG_CAP_CGX },
	{ UFRM_BACK, 0, DEBUG_POS(0), DEBUG_STR_W, DEBUG_STR_H, DEBUG_SUB_PAL, DEBUG_CGX(0) },
	{ UFRM_BACK, 0, DEBUG_POS(1), DEBUG_STR_W, DEBUG_STR_H, DEBUG_SUB_PAL, DEBUG_CGX(1) },
	{ UFRM_BACK, 0, DEBUG_POS(2), DEBUG_STR_W, DEBUG_STR_H, DEBUG_SUB_PAL, DEBUG_CGX(2) },
	{ UFRM_BACK, 0, DEBUG_POS(3), DEBUG_STR_W, DEBUG_STR_H, DEBUG_SUB_PAL, DEBUG_CGX(3) },
	{ UFRM_BACK, 0, DEBUG_POS(4), DEBUG_STR_W, DEBUG_STR_H, DEBUG_SUB_PAL, DEBUG_CGX(4) },
};

#include "system/msgdata_util.h"

// 公開関数: poke_tool.c内でデータをセット
void BCUse_DebugSetPerformance( int perIdx, int cond, int rev, int add, int base, int min, int max, int result )
{
	GF_ASSERT( perIdx < PM_PERFORMANCE_MAX );

	perIdx = g_PerformancePosIdxTbl[ perIdx ];

	wkDebugPer[ perIdx ].cond = cond;
	wkDebugPer[ perIdx ].rev = rev;
	wkDebugPer[ perIdx ].add = add;
	wkDebugPer[ perIdx ].base = base;
	wkDebugPer[ perIdx ].min = min;
	wkDebugPer[ perIdx ].max = max;
	wkDebugPer[ perIdx ].result = result;
}

// BMPWINを通してスクリーンに転送リクエスト
static void Debug_PrintElem( BC_USEWORK* wk, GF_BGL_BMPWIN* win, int msg_idx )
{
	STRBUF* strbuf;
	BC_USE_MSG* msg = &wk->msg;

	GF_ASSERT(wk);
	GF_ASSERT(win);

	strbuf = MSGDAT_UTIL_AllocExpandString( msg->wset, msg->man, msg_idx, wk->heapID );
	GF_STR_PrintColor( win, FONT_SYSTEM, strbuf, 0, 0, MSG_ALLPUT, GF_PRINTCOLOR_MAKE(1,2,0), NULL );

	GF_BGL_BmpWinOnVReq( win );

	STRBUF_Delete( strbuf );
}

// 情報を出力
static void Debug_PrintPerformance( BC_USEWORK* wk, int mode )
{
	int i;
	GF_BGL_BMPWIN win[ DEBUG_PRINT_NUM ];

	// フォントロード
	TalkFontPaletteLoad( PALTYPE_SUB_BG, 15*0x20, wk->heapID );

	// -- 生成
	for( i=0; i<DEBUG_PRINT_NUM; i++ )
	{
		GF_BGL_BmpWinAddEx( wk->bgl, &win[i], &c_DebugBmpWinData[i] );
		GF_BGL_BmpWinDataFill( &win[i], 0 );
	}

	// -- 表示

	// キャプション
	switch( mode )
	{
		case DEBUG_DISP_MODE_BEFORE : Debug_PrintElem( wk, &win[0], msg_debug_before ); break;
		case DEBUG_DISP_MODE_AFTER : Debug_PrintElem( wk, &win[0], msg_debug_after ); break;
		default : GF_ASSERT(0);
	}

	for( i=0; i<PM_PERFORMANCE_MAX; i++ )
	{
		BC_USE_MSG* msg = &wk->msg;

		WORDSET_RegisterNumber( msg->wset, 0, wkDebugPer[i].cond, 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		WORDSET_RegisterNumber( msg->wset, 1, wkDebugPer[i].rev, 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		WORDSET_RegisterNumber( msg->wset, 2, wkDebugPer[i].add, 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		WORDSET_RegisterNumber( msg->wset, 3, wkDebugPer[i].base, 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		WORDSET_RegisterNumber( msg->wset, 4, wkDebugPer[i].min, 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		WORDSET_RegisterNumber( msg->wset, 5, wkDebugPer[i].max, 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		WORDSET_RegisterNumber( msg->wset, 6, wkDebugPer[i].result, 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_DEFAULT );
		Debug_PrintElem( wk, &win[1+i], msg_debug_elem );
	}

	// -- 削除
	for( i=0; i<DEBUG_PRINT_NUM; i++ )
	{
		GF_BGL_BmpWinDel( &win[i] );
	}
}

// パフォーマンス取得時と同時に上画面に計算経過を表示する
static void Debug_GetPokePerformance(BC_USEWORK* wk, BC_USE_POKE* poke, int debug_disp_mode )
{
	DebugPokeTool_CallByBCUseFlag = TRUE;
	GetPokePerformance(&poke->prm,poke->pp,&poke->pc,wk->heapID);
	Debug_PrintPerformance( wk, debug_disp_mode );
	DebugPokeTool_CallByBCUseFlag = FALSE;
}

#endif // PM_DEBUG

////////////////////////////////////////////////////////////////
///ローカル関数
////////////////////////////////////////////////////////////////
static int sub_InputExe(BC_USEWORK* wk,int code)
{
	switch(code){
	case EXE_CODE_USE:
		sub_UseJuice(wk);

		Snd_SePlay(SE_BC_DECIDE);
		BCUseSub_ButtonWrite(wk,BTN_ANM_USE);
		return SEQ_USE_EFF;
	case EXE_CODE_BACK:
		Snd_SePlay(SE_BC_CANCEL);
		BCUseSub_ButtonWrite(wk,BTN_ANM_BACK);
		return SEQ_FADE_OUT;
	case EXE_CODE_UP:
		wk->pos = (wk->pos-1+wk->poke_num)%wk->poke_num;
		Snd_SePlay(SE_BC_SELECT);
		sub_PageDraw(wk,wk->pos);
		return SEQ_MAIN;
	case EXE_CODE_DOWN:
		wk->pos = (wk->pos+1)%wk->poke_num;
		Snd_SePlay(SE_BC_SELECT);
		sub_PageDraw(wk,wk->pos);
		return SEQ_MAIN;
	}
	return SEQ_MAIN;
}

/**
 *	@brief	キー入力取得
 */
static int sub_KeyInput(BC_USEWORK* wk)
{
	if(sys.trg & PAD_BUTTON_KTST_CHG){
		wk->key_mode = APP_KTST_KEY;
	}

	if(sys.trg & PAD_BUTTON_CANCEL){
		return sub_InputExe(wk,EXE_CODE_BACK);
	}
	if(sys.trg & PAD_BUTTON_DECIDE){
		return sub_InputExe(wk,EXE_CODE_USE);
	}
	if(sys.trg & PAD_KEY_UP){
		return sub_InputExe(wk,EXE_CODE_UP);
	}
	if(sys.trg & PAD_KEY_DOWN){
		return sub_InputExe(wk,EXE_CODE_DOWN);
	}
	return SEQ_MAIN;
}

/**
 *	@brief	タッチ入力取得
 */
static int sub_TouchInput(BC_USEWORK* wk,BOOL* touch_f)
{
	int ret;

	static const RECT_HIT_TBL TpRect[] = {
	//	{0,191,0,255}, ty,by,lx,rx
		{TP_USE_Y,TP_USE_Y+TP_USE_H,TP_USE_X,TP_USE_X+TP_USE_W},
		{TP_BACK_Y,TP_BACK_Y+TP_BACK_H,TP_BACK_X,TP_BACK_X+TP_BACK_W},
		{RECT_HIT_END,0,0,0},
	};
	ret = GF_TP_HitTrg(TpRect);

	if(ret == RECT_HIT_NONE){
		return SEQ_MAIN;
	}
	*touch_f = TRUE;
	wk->key_mode = APP_KTST_TOUCH;

	return sub_InputExe(wk,ret);
}


/**
 *	@brief	VBlank関数
 */
static void BongUseVBlank(void * work)
{
	BC_USEWORK* wk = (BC_USEWORK*)work;
	//アクター転送
	if(wk->pActSys != NULL){
		CATS_RenderOamTrans();
	}
	BongUse3D_VBlank(wk->p3d_wk);

	DoVramTransferManager();	// Vram転送マネージャー実行
	GF_BGL_VBlankFunc( wk->bgl );
	OS_SetIrqCheckFlag( OS_IE_V_BLANK);
}

/**
 *	@brief	vramバンク設定
 */
static void sub_VBankSet(void)
{
	GF_BGL_DISPVRAM vramSetTable = {
		GX_VRAM_BG_128_C,				// メイン2DエンジンのBG
		GX_VRAM_BGEXTPLTT_NONE,			// メイン2DエンジンのBG拡張パレット
		GX_VRAM_SUB_BG_32_H,			// サブ2DエンジンのBG
		GX_VRAM_SUB_BGEXTPLTT_NONE,		// サブ2DエンジンのBG拡張パレット
		GX_VRAM_OBJ_16_G,				// メイン2DエンジンのOBJ
		GX_VRAM_OBJEXTPLTT_NONE,		// メイン2DエンジンのOBJ拡張パレット
		GX_VRAM_SUB_OBJ_16_I,			// サブ2DエンジンのOBJ
		GX_VRAM_SUB_OBJEXTPLTT_NONE,	// サブ2DエンジンのOBJ拡張パレット
		GX_VRAM_TEX_01_AB,				// テクスチャイメージスロット
		GX_VRAM_TEXPLTT_0_F			// テクスチャパレットスロット
	};
	GF_Disp_SetBank( &vramSetTable );
}

/*
 *	@brief	BGL初期化
 */
static void sub_BGLInit(BC_USEWORK* wk)
{
	sub_VBankSet();

	wk->bgl = GF_BGL_BglIniAlloc(wk->heapID);
	{	//BG SYSTEM
		GF_BGL_SYS_HEADER BGsys_data = {
			GX_DISPMODE_GRAPHICS,GX_BGMODE_0,GX_BGMODE_0,GX_BG0_AS_3D
		};
		GF_BGL_InitBG(&BGsys_data);
	}
	//上画面をサブ,下画面をメインに切り替え
	GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);

	{	// 上画面　背景
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0x7800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			UFRM_BACK_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, UFRM_BACK, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, UFRM_BACK );
	}

	{	// 下画面　テキスト面(各種ウィンドウ)
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01,
			DFRM_MSG_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_MSG, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_MSG );
	}

	{	// 下画面 ベーステキスト描画面
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01,
			DFRM_TEXT_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_TEXT, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_TEXT );
	}

	{	// 下画面　背景
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			DFRM_BACK_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_BACK, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_BACK );
	}


	GF_BGL_ClearCharSet( UFRM_BACK, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_MSG, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_TEXT, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_BACK, 32, 0, wk->heapID );
}

/**
 * @brief	BGL解放
 */
static void sub_BGLRelease(BC_USEWORK* wk)
{

	GF_BGL_BGControlExit(wk->bgl, DFRM_BACK );
	GF_BGL_BGControlExit(wk->bgl, DFRM_TEXT );
	GF_BGL_BGControlExit(wk->bgl, DFRM_MSG );
	GF_BGL_BGControlExit(wk->bgl, UFRM_BACK );

	sys_FreeMemoryEz(wk->bgl);

	//上画面をメイン,下画面をサブに戻す
	GX_SetDispSelect(GX_DISP_SELECT_MAIN_SUB);
}
/**
 * @brief	2Dリソース初期化
 */
static void sub_2DResInit(BC_USEWORK* wk)
{
	ARCHANDLE* handle;

	//アーカイブのハンドルを取得
	handle = ArchiveDataHandleOpen(ARC_BONG_USE_GRA,wk->heapID);

	//メイン下画面背景転送
	ArcUtil_HDL_PalSet( handle,
			NARC_bong_use_gra_bgd_nclr,PALTYPE_MAIN_BG, 0, 0, wk->heapID);
	ArcUtil_HDL_BgCharSet( handle,
			NARC_bong_use_gra_bgd_lz_ncgr, wk->bgl, DFRM_BACK, 0, 0, TRUE, wk->heapID);
	ArcUtil_HDL_ScrnSet( handle,
			NARC_bong_use_gra_bgd_back_lz_nscr, wk->bgl, DFRM_BACK, 0, 0, TRUE, wk->heapID);

	//サブ上画面背景転送
	ArcUtil_HDL_PalSet( handle,
			NARC_bong_use_gra_bgu_nclr,PALTYPE_SUB_BG, 0, 0, wk->heapID);
	ArcUtil_HDL_BgCharSet( handle,
			NARC_bong_use_gra_bgu_lz_ncgr, wk->bgl, UFRM_BACK, 0, 0, TRUE, wk->heapID);
	ArcUtil_HDL_ScrnSet( handle,
			NARC_bong_use_gra_bgu_back_lz_nscr, wk->bgl, UFRM_BACK, 0, 0, TRUE, wk->heapID);

	wk->grap_h = handle;
	//会話ウインドウグラフィック転送
	TalkWinGraphicSet(wk->bgl,DFRM_MSG,
		BMP_TALK_WIN_CGX, BMP_TALK_WIN_PAL,wk->win_type, wk->heapID);
	TalkFontPaletteLoad( PALTYPE_MAIN_BG, TALK_FONT_PAL*0x20, wk->heapID );

	//ブレンド設定
	G2_SetBlendAlpha(ALPHA_MASK_1ST,ALPHA_MASK_2ND,ALPHA_FIRST,ALPHA_SECOND);
}

/**
 * @brief	2Dリソース解放
 */
static void sub_2DResRelease(BC_USEWORK* wk)
{
	//ハンドル解放
	ArchiveDataHandleClose( wk->grap_h );
	G2_SetBlendAlpha(GX_BLEND_PLANEMASK_NONE,GX_BLEND_PLANEMASK_NONE,31,0);
}

/**
 *	@brief	メッセージデータ初期化
 */
static void sub_MsgDataInit(BC_USEWORK* wk)
{
	int i;

	//タッチフォントロード
	FontProc_LoadFont(FONT_TOUCH,wk->heapID);

	MsgPrintSkipFlagSet( MSG_SKIP_ON );
	MsgPrintTouchPanelFlagSet( MSG_TP_ON );

	wk->msg.man = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,
			NARC_msg_bong_use_dat,wk->heapID);

	wk->msg.wset = WORDSET_CreateEx(WORDSET_BCUSE_BUFNUM,WORDSET_BCUSE_BUFLEN,wk->heapID);
	wk->msg.tmp = STRBUF_Create(BCUSE_MSG_BUFLEN,wk->heapID);
	wk->msg.str = STRBUF_Create(BCUSE_MSG_BUFLEN,wk->heapID);

	wk->msg.level = MSGMAN_AllocString(wk->msg.man,msg_level);
	for(i = 0;i < 2;i++){
		wk->msg.sex[i] = MSGMAN_AllocString(wk->msg.man,msg_osu+i);
	}
}

/**
 *	@brief	メッセージデータ解放
 */
static void sub_MsgDataRelease(BC_USEWORK* wk)
{
	int i;

	//文字列バッファ削除
	STRBUF_Delete(wk->msg.sex[1]);
	STRBUF_Delete(wk->msg.sex[0]);
	STRBUF_Delete(wk->msg.level);
	STRBUF_Delete(wk->msg.str);
	STRBUF_Delete(wk->msg.tmp);
	WORDSET_Delete(wk->msg.wset);

	MSGMAN_Delete(wk->msg.man);

	MsgPrintTouchPanelFlagSet( MSG_TP_OFF );
	MsgPrintSkipFlagSet( MSG_SKIP_OFF );

	//タッチフォントアンロード
	FontProc_UnloadFont(FONT_TOUCH);
}

/**
 *	@brief	BMPウィンドウ初期化
 */
static void sub_BmpWinAdd(BC_USEWORK* wk)
{
	int i;

	static const BMPWIN_DAT BmpWinData[] = {
	 {	// 「メッセージウィンドウ」
		BMP_MSG_FRM, BMP_MSG_PX, BMP_MSG_PY,
		BMP_MSG_SX, BMP_MSG_SY, BMP_MSG_PAL, BMP_MSG_CGX
	 },
	 {	// 「つかうボタン」
		BMP_USE_FRM, BMP_USE_PX, BMP_USE_PY,
		BMP_USE_SX, BMP_USE_SY, BMP_USE_PAL, BMP_USE_CGX
	 },
	 {	// 「もどるボタン」
		BMP_BACK_FRM, BMP_BACK_PX, BMP_BACK_PY,
		BMP_BACK_SX, BMP_BACK_SY, BMP_BACK_PAL, BMP_BACK_CGX
	 },
	 {	// 「タイトルウィンドウ」
		BMP_TITLE_FRM, BMP_TITLE_PX, BMP_TITLE_PY,
		BMP_TITLE_SX, BMP_TITLE_SY, BMP_TITLE_PAL, BMP_TITLE_CGX
	 },
	 {	// 「ニックネームウィンドウ」
		BMP_NAME_FRM, BMP_NAME_PX, BMP_NAME_PY,
		BMP_NAME_SX, BMP_NAME_SY, BMP_NAME_PAL, BMP_NAME_CGX
	 },
	};

	for( i=0; i<=WIN_NAME; i++ ){
		GF_BGL_BmpWinAddEx( wk->bgl, &wk->win[i], &BmpWinData[i] );
		GF_BGL_BmpWinDataFill( &wk->win[i], 0 );
	}
	for(i = 0;i < PM_PERFORMANCE_MAX;i++){
		GF_BGL_BmpWinAdd( wk->bgl, &wk->win[i+WIN_PRM01], BMP_PRM_FRM,
			BMP_PRM_PX, (i*BMP_PRM_OY)+BMP_PRM_PY,
			BMP_PRM_SX, BMP_PRM_SY, BMP_PRM_PAL, (BMP_PRM_CGX_SIZ*i) + BMP_PRM_CGX );
		GF_BGL_BmpWinDataFill( &wk->win[i+WIN_PRM01], 0 );
	}
	//YesNoボタンシステムワーク確保
	wk->ynbtn_wk = TOUCH_SW_AllocWork(wk->heapID);
}

/**
 *	@brief	BMPウィンドウ解放
 */
static void sub_BmpWinDel(BC_USEWORK* wk)
{
	int i;
	for( i=0; i<WIN_MAX; i++ ){
		GF_BGL_BmpWinOff( &wk->win[i] );
		GF_BGL_BmpWinDel( &wk->win[i] );
	}
	//YesNoボタンシステムワーク解放
	TOUCH_SW_FreeWork( wk->ynbtn_wk );
}

/**
 *	@brief	セルアクターシステム初期化
 */
static void sub_ActorSysInit(BC_USEWORK* wk)
{
	initVramTransferManagerHeap(32,wk->heapID);

	//セルアクターシステム初期化
	wk->pActSys = CATS_AllocMemory(wk->heapID);

	CATS_SystemInit( wk->pActSys,
		&bonguse_coi,&bonguse_ccmm,BONGUSE_ACTPAL_NUM );

	//OAM初期化
	REND_OAM_UtilOamRamClear_Main(wk->heapID);
	REND_OAM_UtilOamRamClear_Sub(wk->heapID);

	//セルアクターリソース初期化
	wk->pActRes = CATS_ResourceCreate(wk->pActSys);
	CATS_ClactSetInit( wk->pActSys, wk->pActRes,BC_ACTOR_MAX);

	CATS_ResourceLoadBinaryEx( wk->pActSys, wk->pActRes,
		&bonguse_actres_list,CATS_CGXOFS_AREA,CATS_PLTTOFS_AREA);
}

/**
 *	@brief	セルアクターシステム解放
 */
static void sub_ActorSysRelease(BC_USEWORK* wk)
{
	//リソース解放
	CATS_ResourceDestructor(wk->pActSys,wk->pActRes);
	wk->pActRes = NULL;

	//システムワーク解放
	CATS_FreeMemory(wk->pActSys);
	wk->pActSys = NULL;
	DellVramTransferManager();

	//OAM初期化
	REND_OAM_UtilOamRamClear_Main(wk->heapID);
}
/*
 *	@brief	セルアクター初期化
 */
static void sub_ActorInit(BC_USEWORK* wk)
{
	sub_ActorSysInit(wk);
	sub_ActorObjMake(wk);

	GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );
}

/**
 *	@brief	セルアクター解放
 */
static void sub_ActorRelease(BC_USEWORK* wk)
{
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_OFF );

	sub_ActorObjDelete(wk);
	sub_ActorSysRelease(wk);
}

/**
 *	@brief	セルアクターオブジェクト作成
 */
static void sub_ActorObjMake(BC_USEWORK* wk)
{
	int i,j;
	u8	idx;

	static const TCATS_OBJECT_ADD_PARAM	ActAddParam[] =
	{
		{	// 使うボタン
			ACTRES_NORMAL,	//ID
			ACT_USE_PX, ACT_USE_PY, 0,	//x,y,z
			ANM_USE, ACT_SPRI_USE, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// 戻るボタン
			ACTRES_NORMAL,	//ID
			ACT_BACK_PX, ACT_BACK_PY, 0,	//x,y,z
			ANM_BACK, ACT_SPRI_BACK, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// ポットアイコン
			ACTRES_NORMAL,	//ID
			ACT_POT_PX, ACT_POT_PY, 0,	//x,y,z
			ANM_POT_UP, ACT_SPRI_POT, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// UpDownアイコン
			ACTRES_NORMAL,	//ID
			ACT_UPDOWN_PX, ACT_UPDOWN_PY, 0,	//x,y,z
			ANM_UP, ACT_SPRI_UPDOWN, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// スターアイコン
			ACTRES_NORMAL,	//ID
			ACT_STAR_PX, ACT_STAR_PY, 0,	//x,y,z
			ANM_STAR_N, ACT_SPRI_STAR, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
	};

	for(i = 0;i <= ACT_POT;i++){
		wk->pAct[i] = CATS_ObjectAdd( wk->pActSys, wk->pActRes, &ActAddParam[i] );
		CLACT_SetDrawFlag(wk->pAct[i], TRUE );
		CLACT_SetAnmFlag(wk->pAct[i], TRUE);
		CLACT_BGPriorityChg( wk->pAct[i], DFRM_3D_PRI );
	}
	CLACT_SetDrawFlag(wk->pAct[ACT_POT], FALSE );
	CLACT_SetAffineParam(  wk->pAct[ACT_POT], CLACT_AFFINE_DOUBLE);

	//UpDownアイコンとスター
	for(i = 0;i < PM_PERFORMANCE_MAX;i++){
		idx = ACT_UPDOWN01+g_PerformancePosTbl[i];
		wk->pAct[idx] = CATS_ObjectAdd( wk->pActSys, wk->pActRes, &ActAddParam[3] );

		CATS_ObjectPosSet(wk->pAct[idx],ACT_UPDOWN_PX,ACT_UPDOWN_PY+(i*ACT_UPDOWN_OY));
		CLACT_SetAnmFlag(wk->pAct[idx], TRUE );
		CLACT_SetDrawFlag(wk->pAct[idx], TRUE );

		for(j = 0;j < STAR_NUM_MAX;j++){
			idx = ACT_STAR01+(g_PerformancePosTbl[i]*STAR_NUM_MAX)+j;
			wk->pAct[idx] = CATS_ObjectAdd( wk->pActSys, wk->pActRes, &ActAddParam[4] );

			CATS_ObjectPosSet(wk->pAct[idx],
				ACT_STAR_PX+(j*ACT_STAR_OX),ACT_STAR_PY+(i*ACT_STAR_OY));
			CLACT_SetAnmFlag(wk->pAct[idx], TRUE );
			CLACT_SetDrawFlag(wk->pAct[idx], TRUE );
			CLACT_SetAffineParam(  wk->pAct[idx], CLACT_AFFINE_DOUBLE);
		}
	}
}

/**
 *	@brief	セルアクターオブジェクト削除
 */
static void sub_ActorObjDelete(BC_USEWORK* wk)
{
	int i;

	for(i = 0;i < BONGUSE_ACTMAX;i++){
		if(wk->pAct[i] != NULL){
			CLACT_Delete(wk->pAct[i]);
		}
	}
}


/**
 *	@brief	ポケモンデータ取得
 */
static void sub_GetPokeParam(BC_USE_POKE* poke,const POKEPARTY* party,POKEMON_PARAM* pp,u8 idx,int heapID)
{
	poke->pp = pp;
	poke->idx = idx;
	poke->monsno = PokeParaGet(pp,ID_PARA_monsno,NULL);
	poke->sex = PokeParaGet(pp,ID_PARA_sex,NULL);
	poke->level = PokeParaGet(pp,ID_PARA_level,NULL);
	poke->flip = PokeFormNoPersonalParaGet( poke->monsno,
		PokeParaGet(pp,ID_PARA_form_no,NULL), ID_PER_reverse ) ^ 1;

	poke->name = STRBUF_Create(BUFLEN_POKEMON_NAME,heapID);
	PokeParaGet(pp,ID_PARA_nickname_buf,poke->name);

	//ベース値取得
	GetPokePerformanceBase(poke->pp,&poke->base);
	//コンディション取得
	PokeParty_GetPokeCondition(party,&poke->pc,poke->idx);
}

/**
 *	@brief	ポケモンデータ破棄
 */
static void sub_DelPokeParam(BC_USE_POKE* poke)
{
	STRBUF_Delete(poke->name);
}

/**
 *	@brief	ジュース使用
 */
static void sub_UseJuice(BC_USEWORK* wk)
{
	u8	o_val,n_val;
	int i;
	BC_USE_POKE* poke = &wk->poke[wk->pos];

#ifdef PM_DEBUG
	{	//デバッグ出力のためにパラメータを取得する
		PM_PERFORMANCE deb_pmp;
		OS_Printf("<ジュースをあげる前のパフォーマンス>\n\n");
		GetPokePerformance(&deb_pmp,poke->pp,&poke->pc,wk->heapID);
	}
#endif	//PM_DEBUG

	BongSys_JuicePara2Poke(&wk->juice,wk->party_sv,poke->idx);

	if(wk->sp->juice_id == BONG_JUICE_MINE){
		BonguriSave_UseJuice(wk->bong_sv);
	}

	//新コンディション取得
	OS_Printf("<新コンディション>\n\n");
	PokeParty_GetPokeCondition(wk->party_sv,&poke->pc,poke->idx);

	//旧パフォーマンス確保
	wk->old_prm = poke->prm;

	//新パフォーマンス取得
	OS_Printf("<ジュースをあげた後のパフォーマンス>\n\n");

#ifdef PM_DEBUG
	Debug_GetPokePerformance( wk, poke, DEBUG_DISP_MODE_AFTER );
#else
	GetPokePerformance(&poke->prm,poke->pp,&poke->pc,wk->heapID);
#endif

	//差分取得
	wk->diff_prm_num = 0;
	for(i = 0;i < PM_PERFORMANCE_MAX;i++){
		int idx = g_PerformancePosTbl[i];
		o_val = PERFORMANCE_VALUE(wk->old_prm.param,idx);
		n_val = PERFORMANCE_VALUE(poke->prm.param,idx);

		wk->diff_prm[i] = n_val-o_val;
		if(wk->diff_prm[i] != 0){
			wk->diff_prm_num++;
		}
	}
	wk->use_f = TRUE;	//使ったフラグ立てておく
}

/**
 *	@brief	メッセージウィンドウ描画
 */
static void sub_MsgWinDraw(BC_USEWORK* wk)
{
	BmpTalkWinWrite( &wk->win[WIN_MSG],
		WINDOW_TRANS_OFF, BMP_TALK_WIN_CGX, BMP_TALK_WIN_PAL);
	GF_BGL_BmpWinDataFill(&wk->win[WIN_MSG],FBMP_COL_WHITE);
}

/**
 *	@brief	メッセージ描画
 */
static void sub_MsgPut(BC_USEWORK* wk,MSG_IDX idx)
{
	int speed,id;

	switch(idx){
	case MIDX_USE:
		if(wk->flavor.main.flavor == BONG_FLAVOR_NONE ){
			id = msg_sys_use00;
		}else if(wk->flavor.main.flavor == BONG_FLAVOR_MIX){
			id = msg_sys_use01+wk->flavor.order[0];
		}else{
			id = msg_sys_use01+wk->flavor.main.flavor;
		}
		speed = MSG_ALLPUT;
		break;
	case MIDX_NO_CHANGE:
		id = msg_sys_param_nochg;
		speed = wk->msg_spd;
		break;
	case MIDX_PRM_UP01:
	case MIDX_PRM_UP02:
	case MIDX_PRM_UP03:
	case MIDX_PRM_UP04:
	case MIDX_PRM_UP05:
		id = msg_sys_param_up01+(idx-MIDX_PRM_UP01);
		speed = wk->msg_spd;
		break;
	case MIDX_PRM_DOWN01:
	case MIDX_PRM_DOWN02:
	case MIDX_PRM_DOWN03:
	case MIDX_PRM_DOWN04:
	case MIDX_PRM_DOWN05:
		id = msg_sys_param_down01+(idx-MIDX_PRM_DOWN01);
		speed = wk->msg_spd;
		break;
	default:
		id = idx;
		speed = wk->msg_spd;
		break;
	}
	MSGMAN_GetString(wk->msg.man,id,wk->msg.str);

	wk->msg_idx = GF_STR_PrintColor( &wk->win[WIN_MSG], FONT_TALK, wk->msg.str,
		0,0, speed, FCOL_W_BLACK, NULL );

	if(speed == MSG_ALLPUT){
		GF_BGL_BmpWinOnVReq(&wk->win[WIN_MSG]);
	}
}

/**
 *	@brief	ページ描画
 */
static void sub_PageDraw(BC_USEWORK* wk,int pos)
{
	static const GF_PRINTCOLOR col[] = { FCOL_N_BLUE,FCOL_N_RED };
	BC_USE_POKE* poke = &wk->poke[pos];

	//名前
	GF_BGL_BmpWinDataFill(&wk->win[WIN_NAME],0);
	GF_STR_PrintColor( &wk->win[WIN_NAME], FONT_SYSTEM, poke->name,
		0,0, MSG_NO_PUT, FCOL_N_WHITE, NULL );

	//性別
	if(poke->sex != PM_NEUTRAL){
		GF_STR_PrintColor( &wk->win[WIN_NAME], FONT_SYSTEM, wk->msg.sex[poke->sex],
			64,0, MSG_NO_PUT, col[poke->sex], NULL );
	}

	//レベル
	WORDSET_RegisterNumber( wk->msg.wset, 0, poke->level , 3,
		NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );
	WORDSET_ExpandStr( wk->msg.wset, wk->msg.str ,wk->msg.level);
	GF_STR_PrintColor( &wk->win[WIN_NAME], FONT_SYSTEM, wk->msg.str,
		16,16, MSG_NO_PUT, FCOL_N_BLACK, NULL );

	GF_BGL_BmpWinOnVReq(&wk->win[WIN_NAME]);

	BongUse3D_PokeDel(wk->p3d_wk);
	BongUse3D_PokeAdd(wk->p3d_wk,poke);

	//パフォーマンス値取得
	sub_PerformanceDraw(wk,poke);

}

/**
 *	@brief	パフォーマンスパラメータ描き込み
 */
static void sub_PerformanceParamDraw(BC_USEWORK* wk,BC_USE_POKE* poke,u8 prm_idx)
{
	int i,act_idx;
	u8	val;

	//調子状態表示
	if(poke->pc.condition[prm_idx] == 0){
		CLACT_SetDrawFlag(wk->pAct[ACT_UPDOWN01+prm_idx], FALSE);
	}else{
		CLACT_SetDrawFlag(wk->pAct[ACT_UPDOWN01+prm_idx], TRUE);
		if(poke->pc.condition[prm_idx] > 0){
			CLACT_AnmChg(wk->pAct[ACT_UPDOWN01+prm_idx], ANM_UP);
		}else{
			CLACT_AnmChg(wk->pAct[ACT_UPDOWN01+prm_idx], ANM_DOWN);
		}
	}

	//パフォーマンス値表示
	val = PERFORMANCE_VALUE(poke->prm.param,prm_idx);

	for(i = 0;i < STAR_NUM_MAX;i++)	{
		act_idx = (prm_idx*STAR_NUM_MAX)+i;

		if(i > poke->base.param[prm_idx].max){
			sub_StarViewSet(wk,act_idx,0xFF,FALSE);
			continue;
		}

		if(i > val){
			sub_StarViewSet(wk,act_idx,ANM_STAR_M,TRUE);
		}else{
			sub_StarViewSet(wk,act_idx,ANM_STAR_N+poke->prm.revision[prm_idx],TRUE);
		}
	}
}

/**
 *	@brief	パフォーマンス値取得＆描き込み
 */
static void sub_PerformanceDraw(BC_USEWORK* wk,BC_USE_POKE* poke)
{
	int i;

#ifdef PM_DEBUG
	Debug_GetPokePerformance( wk, poke, DEBUG_DISP_MODE_BEFORE );
#else
	GetPokePerformance(&poke->prm,poke->pp,&poke->pc,wk->heapID);
#endif

	for(i = 0;i < PM_PERFORMANCE_MAX;i++){
		sub_PerformanceParamDraw(wk,poke,i);
	}
}

/**
 *	@brief	スターセット
 */
static void sub_StarViewSet(BC_USEWORK* wk,int idx,u8 anm_no,BOOL draw_f)
{
	CLACT_SetDrawFlag(wk->pAct[ACT_STAR01+idx], draw_f);
	if(anm_no != 0xFF){
		CLACT_AnmChg(wk->pAct[ACT_STAR01+idx], anm_no);
		CLACT_AnmReStart( wk->pAct[ACT_STAR01+idx]);
	}
}

/**
 *	@brief	スターエフェクトタスク生成
 */
static void sub_StarEffSet(BC_USEWORK* wk,u8 prm_id,u8 mode)
{
	STAR_EFF* sp;
	u8	act_idx,target;
	BC_USE_POKE* poke = &wk->poke[wk->pos];

	sp = sys_AllocMemory(wk->heapID,sizeof(STAR_EFF));
	MI_CpuClear8(sp,sizeof(STAR_EFF));

	sp->app_wk = wk;
	sp->mode = mode;
	sp->time = 30;

	target = PERFORMANCE_VALUE(wk->old_prm.param,prm_id);

	if(mode == 0){	//Up
		act_idx = target+wk->diff_ct+1;
		VEC_Set(&sp->scale,FX32_CONST(0.1),FX32_CONST(0.1),0);
		sp->ds = FX_Div(FX32_ONE,FX32_CONST(sp->time));
		sp->rot_dif = 12;
		sp->rot = 0;
//		Snd_SePlay(SE_BCUSE_PARAM_UP);
	}else{	//Down
		act_idx = target-wk->diff_ct;
		VEC_Set(&sp->scale,FX32_CONST(1.1),FX32_CONST(1.1),FX32_ONE);
		sp->ds = -(FX_Div(FX32_ONE,FX32_CONST(sp->time)));
		sp->rot_dif -= 12;
		sp->rot = 360;
//		Snd_SePlay(SE_BCUSE_PARAM_DOWN);
	}

	act_idx += prm_id*STAR_NUM_MAX;
	sp->act = wk->pAct[ACT_STAR01+act_idx];
	CLACT_SetScale(sp->act, &sp->scale);
	sub_StarViewSet(wk,act_idx,ANM_STAR_N+wk->old_prm.revision[prm_id],TRUE);

	TCB_Add( tcb_StarEff, sp, 0);
	++wk->eff_tcb_ct;
	++wk->diff_ct;
}

/**
 *	@brief	スターエフェクト　追加＆拡大
 */
static void tcb_StarEff( TCB_PTR tcb, void* p_work )
{
	u8	n_pos;
	s16	px,py;
	STAR_EFF* sp = (STAR_EFF*)p_work;
	BC_USEWORK* wk = sp->app_wk;

	//現在のrot指定
	sp->rot += sp->rot_dif;

	//スケール
	sp->scale.x += sp->ds;
	sp->scale.y += sp->ds;

	if(--sp->time > 0){
		CLACT_SetRotation(sp->act,RotKeyR(sp->rot));
		CLACT_SetScale(sp->act, &sp->scale);
		return;
	}
	CLACT_SetRotation(sp->act,0);

	VEC_Set(&sp->scale,FX32_ONE,FX32_ONE,FX32_ONE);
	CLACT_SetScale(sp->act, &sp->scale);
	if(sp->mode){
		CLACT_SetDrawFlag(sp->act, FALSE );
	}

	--wk->eff_tcb_ct;

	// メモリ解放
	sys_FreeMemoryEz(p_work);
	TCB_Delete( tcb );
}

/**
 *	@brief	ポケモン拡縮エフェクトタスク生成
 */
static void sub_PokeAffineEffSet(BC_USEWORK* wk)
{
	POKE_AFFINE_EFF* ap;

	ap = sys_AllocMemory(wk->heapID,sizeof(POKE_AFFINE_EFF));
	MI_CpuClear8(ap,sizeof(POKE_AFFINE_EFF));

	ap->app_wk = wk;
	ap->time = 30;
	ap->spd = 12;

	Snd_SePlay(SE_BCUSE_JUICE_USE);

	TCB_Add( tcb_PokeAffineEff, ap, 0);
	++wk->eff_tcb_ct;
}

/**
 *	@brief	ポケモンアフィンエフェクト　追加＆拡大
 */
static void tcb_PokeAffineEff( TCB_PTR tcb, void* p_work )
{
	POKE_AFFINE_EFF* ap = (POKE_AFFINE_EFF*)p_work;
	BC_USEWORK* wk = ap->app_wk;

	if(ap->seq % 2 == 0){
		SoftSpriteParaCalc(wk->p3d_wk->ss,SS_PARA_AFF_X,ap->spd);
		SoftSpriteParaCalc(wk->p3d_wk->ss,SS_PARA_AFF_Y,-ap->spd);
	}else{
		SoftSpriteParaCalc(wk->p3d_wk->ss,SS_PARA_AFF_X,-ap->spd);
		SoftSpriteParaCalc(wk->p3d_wk->ss,SS_PARA_AFF_Y,ap->spd);
	}

	if(ap->time++ < 8){
		return;
	}
	ap->time = 0;
	if(ap->seq++ < 4){
		return;
	}
	SoftSpriteParaSet(wk->p3d_wk->ss,SS_PARA_AFF_X,0x100);
	SoftSpriteParaSet(wk->p3d_wk->ss,SS_PARA_AFF_Y,0x100);
	--wk->eff_tcb_ct;

	// メモリ解放
	sys_FreeMemoryEz(p_work);
	TCB_Delete( tcb );
}

/**
 *	@brief	ポケモンパーティクルエフェクトタスク生成
 */
static void sub_PokeParticleEffSet(BC_USEWORK* wk)
{
	POKE_PARTICLE_EFF* ep;

	ep = sys_AllocMemory(wk->heapID,sizeof(POKE_PARTICLE_EFF));
	MI_CpuClear8(ep,sizeof(POKE_PARTICLE_EFF));

	ep->app_wk = wk;

	TCB_Add( tcb_PokeParticleEff, ep, 0);
	++wk->eff_tcb_ct;
}

/**
 *	@brief	パーティクル再生
 */
static void tcb_PokeParticleEff( TCB_PTR tcb, void* p_work )
{
	POKE_PARTICLE_EFF* ep = (POKE_PARTICLE_EFF*)p_work;
	BC_USEWORK* wk = ep->app_wk;

	switch(ep->seq){
	case 0:
		BongUse3D_ParticleEmitterAdd(wk->p3d_wk,PTCL_BONG_USE_BONG_RING);
		Snd_SePlay(SE_BCUSE_EFF_POWA);
		ep->time = 20;
		ep->seq++;
		break;
	case 1:
		if(ep->time-- > 0){
			break;
		}
		SoftSpritePalFadeSet(wk->p3d_wk->ss,0,16,4,0x7fff);
		BongUse3D_ParticleEmitterAdd(wk->p3d_wk,PTCL_BONG_USE_BONG_KIRA);
		BongUse3D_ParticleEmitterAdd(wk->p3d_wk,PTCL_BONG_USE_BONG_AURA);
		ep->time = 25;
		ep->seq++;
		break;
	case 2:
		if(ep->time-- > 0){
			break;
		}
		Snd_SePlay(SE_BCUSE_EFF_KIRA);
		ep->seq++;
		break;
	case 3:
		if(SoftSpritePalFadeExist(wk->p3d_wk->ss)){
			break;
		}
		if(BongUse3D_ParticleEmitterIsActive(wk->p3d_wk)){
			break;
		}
		Particle_EmitterDeleteAll(wk->p3d_wk->ptc);
#if 0
		WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT, WIPE_TYPE_FADEOUT,
			WIPE_FADE_WHITE, 16, 1/*WIPE_DEF_SYNC*/, wk->heapID);
#endif
		ep->seq++;
		break;
	case 4:
#if 0
		if( !WIPE_SYS_EndCheck()){
			break;
		}
#endif
		WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEIN, WIPE_TYPE_FADEIN,
			WIPE_FADE_WHITE, 6, 6, wk->heapID);
		SoftSpritePalFadeSet(wk->p3d_wk->ss,16,0,4,0x7fff);
		ep->seq++;
		break;
	default:
		if( !WIPE_SYS_EndCheck()){
			break;
		}
		if(SoftSpritePalFadeExist(wk->p3d_wk->ss)){
			break;
		}
		--wk->eff_tcb_ct;

		// メモリ解放
		sys_FreeMemoryEz(p_work);
		TCB_Delete( tcb );
	}
}